View Javadoc
1 /*** 2 * SMClassLoader - 3 * 4 * This class extends the ClassLoader provided 5 * by the BCEL project. 6 * 7 * It instruments the code loaded with the implementation 8 * of the StateMachine provided here. 9 */ 10 11 package junit.quilt.cover.state; 12 13 import java.io.*; 14 15 import java.net.URL; 16 17 import java.util.Set; 18 import java.util.List; 19 import java.util.ArrayList; 20 import java.util.Map; 21 import java.util.HashMap; 22 import java.util.HashSet; 23 import java.util.Iterator; 24 import java.util.Collection; 25 import java.lang.ClassLoader; 26 27 // import java.lang.reflect.Constructor; 28 29 import junit.quilt.cover.generic.*; 30 31 import org.apache.bcel.generic.*; 32 import org.apache.bcel.classfile.*; 33 import org.apache.bcel.Constants; 34 35 import org.apache.commons.graph.*; 36 37 public class SMClassLoader 38 extends MethInstClassLoader 39 { 40 private StateMachineRegistry registry = null; 41 42 protectedSMClassLoader( String packages[],/index.html"> SMClassLoader( String packages[], 43 URL path[], 44 ClassLoader parent, 45 StateMachineRegistry registry ) { 46 super( packages, path, parent ); 47 this.registry = registry; 48 } 49 50 public void instrumentPool(InstContext context) 51 { 52 ConstantPoolGen pool = context.getConstantPoolGen(); 53 54 int visitRef 55 = pool.addMethodref( 56 "junit/quilt/cover/state/SimpleStateMachine", 57 "visit", 58 "(I)V"); 59 60 int startRef 61 = pool.addMethodref( 62 "junit/quilt/cover/state/SimpleStateMachine", 63 "start", 64 "()V" ); 65 66 context.put( "visitRef", new Integer( visitRef )); 67 context.put( "startRef", new Integer( startRef )); 68 } 69 70 public void instrumentMethod( InstContext context, 71 ControlFlowGraph cfg ) { 72 ClassGen clazz = context.getClassGen(); 73 74 // Initialize some variables. . . 75 int startRef = ((Integer) context.get("startRef")).intValue(); 76 int visitRef = ((Integer) context.get("visitRef")).intValue(); 77 int fieldVar = cfg.makeNewLocal("MSM", 78 new ObjectType("junit.quilt.cover.state.SimpleStateMachine")); 79 80 int numVertices = cfg.getVertices().size() + 4; 81 SimpleStateMachine ssm = new SimpleStateMachine( clazz.getFileName(), 82 numVertices); 83 int fieldRef = addStaticField( context, 84 new ObjectType("junit.quilt.cover.state.SimpleStateMachine"), 85 ssm); 86 87 // Add Initialization Code 88 junit.quilt.cover.state.InitVertex init = 89 new junit.quilt.cover.state.InitVertex(fieldVar, 90 fieldRef, 91 startRef); 92 93 BlockVertex start = cfg.getStartVertex(); 94 cfg.setStartVertex( init ); 95 96 FlowControlEdge initEdge = 97 getEdgeFactory().makeNormalEdge( init, start ); 98 cfg.addEdge( initEdge ); 99 100 // Add the Visit code 101 Set blockSet = cfg.getVertices(); 102 Vertex blocks[] = (Vertex []) blockSet.toArray( new Vertex[ blockSet.size() ]); 103 104 Map labels = new HashMap(); // BLOCK X INDEX 105 for (short i = 0; i < blocks.length; i++) { 106 BlockVertex bv = (BlockVertex) blocks[i]; 107 108 if ((bv != cfg.getStartVertex()) && 109 (bv != cfg.getEndVertex()) && 110 (!(bv instanceof CallVisitVertex)) ) { 111 labels.put( bv, new Integer( i )); 112 ssm.addState( i, bv ); 113 114 Iterator edges = new HashSet( cfg.getEdges() ).iterator();; 115 while (edges.hasNext()) { 116 FlowControlEdge cEdge = (FlowControlEdge) edges.next(); 117 if (cfg.getSource( cEdge ) == bv) { 118 // Edge leads away. . . 119 Vertex target = cfg.getTarget(cEdge); 120 if (labels.containsKey( target )) { 121 int iTarget = 122 ((Integer) labels.get(target)).intValue(); 123 ssm.addTransition( i, iTarget ); 124 } 125 } else { 126 // Edge leads in . . . 127 Vertex source = cfg.getSource(cEdge); 128 if (! ((cfg.getSource(cEdge) instanceof CallVisitVertex) || 129 (cfg.getTarget(cEdge) instanceof CallVisitVertex))) { 130 if (labels.containsKey( source )) { 131 int iSource = 132 ((Integer) labels.get(source)).intValue(); 133 ssm.addTransition( iSource, i ); 134 } 135 instrumentEdge( context, cfg, cEdge, 136 new CallVisitVertex( fieldVar, visitRef, i )); 137 } 138 } 139 } 140 } 141 } 142 143 // Write the StateMachine to the StateMachineRegistry 144 registry.bind( clazz.getClassName(), 145 cfg.getMethodName(), 146 ssm ); 147 } 148 149 }

This page was automatically generated by Maven